# coding: utf8

import numpy as np


class NumpySplit:

    a = np.arange(1, 31).reshape(10, 3)

    @staticmethod
    def demo_np_split():
        a_split = np.split(NumpySplit.a, 5)
        print(NumpySplit.a)
        print("split to 5 groups:")
        for j, sa in enumerate(a_split):
            print("group{}:".format(j))
            print(sa)

    @staticmethod
    def demo_ndarray_split():
        a = np.arange(9)
        a_split = np.array_split(a, 4)
        print(">>> a")
        print(">>> np.array_split(a, 4)")
        print(a_split)

        a = np.arange(1, 31).reshape(3, 10)
        print(">>> a")
        print(a)
        a_split = np.array_split(a, 3, axis=1)
        print("array_split(a, 3, axis=1) to 3 groups on axis=1:")
        for j, sa in enumerate(a_split):
            print("group{}:".format(j))
            print(sa)


class NumpyMerge:
    a = np.arange(1, 5).reshape((2, 2))
    b = np.arange(100, 401, 100).reshape((2, 2))
    c = np.arange(8).reshape((2, 2, 2))

    @classmethod
    def demo_append(cls):
        a = cls.a
        b = cls.b
        # append
        print("-"*30)
        print("# append a,b on axis=0")
        print(">>> np.append(a, b, axis=0)")
        print(np.append(a, b, axis=0))
        print("-"*30)

        print("# append a,b on axis=1")
        print(">>> np.append(a, b, axis=1)")
        print(np.append(a, b, axis=1))

        print("# append a,(b, a) on axis=1")
        print(">>> np.append(a, (b,a), axis=0)")
        print(np.append(a, (b, a)))

    @classmethod
    def demo_concatenate(cls):
        a = cls.a
        b = cls.b
        c = cls.c

        # concatenate
        print("-"*30)
        print("# concatenate a,b on axis=0")
        print(">>> np.concatenate((a, b))")
        print(np.concatenate((a, b), axis=0))
        print("-"*30)

        print("# concatenate a,b on axis=1")
        print(">>> np.concatenate((a, b), axis=1)")
        print(np.concatenate((a, b), axis=1))

        print("# concatenate a,b on axis=1")
        print(">>> np.concatenate((a, b, c), axis=2)")
        print(np.concatenate((a, b, c.reshape((2, 4))), axis=1))

        print("# concatenate by casting")
        print(">>> np.concatenate(([1, 2], ['3', '4']), casting='safe')")
        print(np.concatenate(([1, 2], ['3', '4']), casting='safe'))

        print("# concatenate by casting")
        print(">>> np.concatenate(([1, 2], ['3', '4']), casting='unsafe')")
        print(np.concatenate(([1, 2], ['3', '4']), casting='unsafe'))

    @classmethod
    def demo_stack(cls):
        a = cls.a
        b = cls.b

        print("-"*30)
        print(">>> cls.a")
        print(cls.a)
        print(">>> b")
        print(cls.b)

        # stack on axis=0
        print("-"*30)
        print("# stack a,b on axis=0")
        print(">>> np.stack((a, b), axis=0)")
        print(np.stack((a, b), axis=0))

        # stack on axis=1
        print("-"*30)
        print("# stack a,b on axis=1")
        print(">>> np.stack((a, b), axis=1)")
        print(np.stack((a, b), axis=1))

        # stack on axis=2
        print("-"*30)
        print("# stack a,b on axis=2")
        print(">>> np.stack((a, b), axis=2)")
        print(np.stack((a, b), axis=2))

        # stack error: not same shape
        # print("-"*30)
        # print("# stack a,b on axis=2")
        # print(">>> np.stack((a, b, c), axis=2)")
        # print(np.stack((a, b, c), axis=0))


def task():
    group_num1 = 10
    group_num2 = 10
    group_num3 = 5
    division_num = 3
    a = np.random.randint(0, 101, group_num1*2).reshape((group_num1, 2))
    b = np.random.randint(0, 101, group_num2*3).reshape((group_num2, 3))
    c = np.random.randint(0, 101, group_num3*5).reshape((group_num3, 5))
    d = np.append(a, b, axis=1)
    e1 = d[d[:, 0] > 50, :]
    e2 = c[3:6, :]
    f = np.concatenate((e1, e2), axis=0)
    g = np.array_split(f, indices_or_sections=division_num, axis=0)
    print(
        f"""
        >>> a
        {a}
        >>> b
        {b}
        >>> c
        {c}
        >>> d = np.append(a, b, axis=1)
        {d}
        >>> e1 = d[d[:, 0] > 50, :]
        {e1}
        >>> e2 = c[2:5, :]
        {e2}
        >>> f = np.concatenate((d, c), axis=0)
        {f}
        >>> g = np.split(f, indices_or_sections=3, axis=0)
        >>> g
    {g}
        """
    )


def expand():
    # 将任务实现中3组学生成绩先全部合并，再选取5至15位成绩数据（不包括第15位），在将数据按照课程分为两组。
    group_num1 = 10
    group_num2 = 10
    group_num3 = 5
    division_num = 3
    g1 = np.random.randint(0, 101, group_num1*2).reshape((group_num1, 2))
    g2 = np.random.randint(0, 101, group_num2*3).reshape((group_num2, 3))
    g3 = np.random.randint(0, 101, group_num3*5).reshape((group_num3, 5))

    print(g1)
    print(g2)
    print(g3)
    g12 =np.append(g1, g2, axis=1)
    print(">>> g12 = np.append(g1, g2)")
    print(g12)
    print(">>> g123 = np.concatenate((g12, g3), dtype=np.float16)")
    g123 = np.concatenate((g12, g3), dtype=np.float16)
    print(g123)

    g12_515 = g123[4:14, :]
    print(">>> g12_515 = g12[4:14, :]")
    print(g12_515)

    g_split = np.array_split(g12_515, 2, axis=1)
    print(">>> np.array_split(g12_515, 2, axis=1)")
    for j, g in enumerate(g_split):
        print("group{}:".format(j))
        print(g)


if __name__ == '__main__':
    # NumpySplit.demo_ndarray_split()
    # NumpySplit.demo_np_split()
    # NumpyMerge.demo_stack()
    task()
    # expand()
